import logging as log
from app.exts import ironman_redis as redis


class AbstractInd:

    def get_name(self):
        pass

    def get_db(self):
        return "cg"

    def get_sql(self, params) -> str:
        pass

    def get_data_source(self):
        return ""

    def __init__(self, infludb_client, params, mysql_client=None):
        self.influx_client = infludb_client
        self.params = params
        self.mysql_client = mysql_client

    def get_influx_result(self, result_set, key):
        if len(result_set) > 0:
            return float(result_set[0][0][key])

    def cache_wrapper(func):
        def wrapper(self, *arg):
            db_name = self.get_db()

            if self.get_data_source() == 'mysql':
                conn, cursor = self.mysql_client.connect(db=db_name)
                self.mysql_cursor = cursor
            try:
                res = func(self, *arg)
                if res is None or res == 0:
                    r = self.get_cache()
                    return r
                self.set_cache(res)
                return res
            except Exception as e:
                raise e
            finally:
                if self.get_data_source() == 'mysql':
                    self.mysql_client.connect_close(conn, cursor)

        return wrapper

    @cache_wrapper
    def get_result(self):
        cursor = self.mysql_cursor
        sql: str = self.get_sql(self.params)
        cursor.execute(sql)
        result = cursor.fetchone()

        if result and result[self.get_name()] is not None:
                return result[self.get_name()]

        return 0

    def set_cache(self, v):
        # log.info("set cache into redis {}:{}".format(self.get_name(),v))
        redis.hset("indicators", self.get_name(), v)

    def get_cache(self):
        cache = redis.hget("indicators", self.get_name())

        return float(cache) if cache is not None else 0


class RealTimeInfluxDbInd(AbstractInd):

    def get_name(self):
        return self.params.get("ind_name")

    def get_sql(self, params):
        if params.get("table") is not None:
            sql = """
            SELECT  mean(value)  AS  {ind_name}  FROM CG where code='{ind_name}' and time >= '{dt_start_tz}' and time <= '{dt_end_tz}'
            """.format(**params)
        else:
            sql = """
            SELECT  mean(value)  AS  {ind_name}  FROM {ind_name}
            where time >= '{dt_start_tz}' and time <= '{dt_end_tz}'
            """.format(**params)
        # log.info(sql)

        return sql

    @AbstractInd.cache_wrapper
    def get_result(self):
        ind_name = self.get_name()
        sql = self.get_sql(self.params)
        client = self.influx_client

        result_set = list(client.query(sql))
        value = self.get_influx_result(result_set, ind_name)

        return value
